package com.budgetme.graphing;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import com.budgetme.database.Database;
import com.budgetme.database.Provider;
import com.budgetme.graphing.GraphViewSeries.GraphViewData;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Paint;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;

public class BudgetExpenseGraph extends LineGraphView {
	private static final String TAG = "BudgetExpenseGraph";
	
    private static final int FREQUENCY = 1440;
    private static final int PROJECTION = 7;
    
    private ContentResolver mContentResolver;
    
    private int mId;

	public BudgetExpenseGraph(Context context, String title, int budgetId) {
		super(context, title);
		
		mId = budgetId;
		
		
		mContentResolver = context.getContentResolver();
		
		
		
		init();
	}
	
	public void init() {
		
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
		
		// TODO: Optimization of SparseArray, no initial size, or initial size?  Is it faster to have it blank and add to it or figure out the size first?
		SparseArray<Double> expenseMap = new SparseArray<Double>();
		
		double totalSpent = 0.0;
		
		// Get details about the budget
		int lifecycle;
		double budget;
		
		Uri uri = Uri.withAppendedPath(Database.tbl_budgets.CONTENT_URI, String.valueOf(mId));
		Cursor cursor = mContentResolver.query(uri, null, null, null, null);
		if (cursor.moveToFirst()) {
			lifecycle = cursor.getInt(cursor.getColumnIndex(Database.tbl_budgets.t_lifecycle));
			budget = cursor.getDouble(cursor.getColumnIndex(Database.tbl_budgets.t_budget));
		} else {
			// TODO: Something is broken if we got here
			return;
		}
		
		cursor.close();
		
		// Get expense information about the bucket
        uri = Uri.withAppendedPath(Database.tbl_expenses.CONTENT_URI, "lifecycle/" + String.valueOf(mId));
		cursor = mContentResolver.query(uri, null, null, null, null);
		
		Date lifecycleStart = null;
		Date lifecycleEnd = null;
		if (cursor.moveToFirst()) {
			try {
				lifecycleStart = format.parse(cursor.getString(cursor.getColumnIndex("l_start")));
				lifecycleEnd = format.parse(cursor.getString(cursor.getColumnIndex("l_end")));
			} catch (ParseException e) {
				// TODO: Will need to figure out what to set the start/end dates to so it doesn't error later
				e.printStackTrace();
			}
		}
		
		while (cursor.moveToNext()) {
			
			String sdate = cursor.getString(cursor.getColumnIndex(Database.tbl_expenses.e_date));
			double spent = cursor.getDouble(cursor.getColumnIndex(Database.tbl_expenses.e_amount));
			
			totalSpent += spent;
			
			Date expenseDate = null;
			try {
				expenseDate = format.parse(sdate);
			} catch (ParseException e) {
				// TODO: Will need to figure out what to set the start/end dates to so it doesn't error later
				e.printStackTrace();
			}  
			
			// Dividing drops the least significant digits, basically forcing a round down.  I think that's what I want :)
            int cycle = (int) ((expenseDate.getTime() - lifecycleStart.getTime()) / (1000 * 60 * FREQUENCY));
            
			expenseMap.put(cycle, expenseMap.get(cycle, 0.0) + spent);
			
		}
		
		
		
		int lifecycleDays = Provider.getLifecyleDays(lifecycle);
		int lifecycleMinutes = lifecycleDays * 1440;
		int cycleCount = lifecycleMinutes / FREQUENCY;
		
		double freqBudget = budget / cycleCount; 		// Budget per cycle
		double freqSpent = totalSpent / cycleCount;		// Avg Spent per cycle
		
		GraphViewData[] graphViewData = new GraphViewData[cycleCount + 7];
		
		double current = 0;
		for(int i = 0; i < cycleCount; i++) {
			current += freqBudget;
			current -= expenseMap.get(i, 0.0);
			
			graphViewData[i] = new GraphViewData(i + 1, current);
			
		}
		
			
		for(int i = 1; i <= 7; i++) {
			current += freqBudget;
			current -= freqSpent;
			
			graphViewData[cycleCount + i - 1] = new GraphViewData(cycleCount + i, current);
			
		}
			

		
      	addSeries(new GraphViewSeries(graphViewData));
      	      	
      	double maxY = getMaxY();
      	double minY = getMinY();
      	
      	double uBoundY = (maxY > 0) ? maxY + 3 : 3;
      	double lBoundY = (minY < 0) ? minY - 3 : -3;
      	
      	formatLabel(3, true);
      	
      	setManualYAxisBounds(uBoundY, lBoundY);
      	
      	setDrawBackground(true);
      	setManualYCenterValue(0);
		
	}

}
